/////////////////////////////////////////////////////////////////////////////
// 这个文件是 JSI 项目的一部分
//
// Copyright (c) 2006 - 2007 (www.xidea.org)
//
// 要查看完整的版权信息和许可信息，请查看源代码中附带的 LICENSE.txt 文件，
// 或者访问 http://xidea.org/ 获得详细信息。
/////////////////////////////////////////////////////////////////////////////

/**
 * 定义 $import, 用以导入脚本[样式]元素
 *
 * 对于大部分 $JSI 的组件，都要求预先初始化 $JSI 环境。
 * requires: boot-browser.js, log.js
 *
 * @package core
 * @copyright (c) 2006 - 2007 (www.xidea.org)
 * @author: dawei jin(jindw@xidea.org)
 * @author: DSONet (dsonet@msn.com)
 * @version $Id: core.js 27 2008-02-16 02:07:05Z dsonet $
 */
/**
 * 导入指定元素（函数、类、变量、样式）至指定目标,默认方式为同步导入，默认目标为全局对象（Global == window(html)）。 
 * <p>导入步骤：</p>
 * <ul>
 *   <li>若元素未装载或依赖未装载，且为异步装载模式，先缓存需要的脚本资源</li> 
 *   <li>若元素未装载或依赖未装载，且为同步非阻塞装载模式，预装载脚本（当前script标签的其他脚本<b>可能</b>继续运行，浏览器不同表现略有不同）; 
 *  并且等待预装载脚本执行之后继续以下步骤</li>
 *   <li>若元素未装载或依赖未装载，装载之</li>
 *   <li>将该元素声明为指定目标的属性(默认目标为全局对象，这时相当于声明了全局变量),若声明为null,则仅返回该对象</li>
 * </ul> 
 * <p><b>全局对象的特殊性:</b></p> 
 * <p>全局对象的属性同时也是全局变量，可以在任何地方直接使用， 
 * 也就是说： 
 * $import函数调用时，默认（未指定target）导入成全局对象属性，等价于声明了一个全局变量。</p> 
 * <p><i>第二个参数只是为优化设计，不保证准确行为，如果发现类库已经导入，则不必延迟或者异步，直接将元素值或引用复制到目标</i></p> 
 * <i><b>该方法为最终用户设计（页面上的脚本）,不推荐类库开发者（托管脚本）使用该函数,除非确实需要（如需要动态导入时）。 
 * 类库开发者可在包中定义脚本依赖完成类似功能。</b></i> 
 * @public 
 * @param {string} path 可以为如下形式(package.ObjectName|package:ObjectName|package.ClassName|package.*| abstractScriptPath|abstractCSSPath)  
 * @param {boolean|Function} [callbackOrLazyLoad=null] 可选参数,默认为null,如果其值为函数，表示异步导入模式；如果其值为真，表示延迟同步导入模式，否则为即时同步导入（默认方式）。 
 * @param {Object} [target] 可选参数，指定导入容器。当第三个参数为有效对象时，导入的元素将赋值成其属性；当第三个参数未指定时(arguments.length<3)，target为全局变量容器,这种情况等价于直接声明的全局变量。 
 * @return {void|Object} 异步导入、同步无阻塞导入、css导入 返回void，同步导入时单个元素返回元素本身，多个返回target对象（默认为全局变量）
 */
var $import = function ()
{
	/*
	 * 已加载的包集合
	 * @type {Object|Package}
	 * @private 
	 */
	var packageMap = {}//loaded package
		, e//try{}catch(e){}
		, uid = 1//unique ID
		//namespace trimer
		, nsRe = /(\b[\$\w]+)[\$\w\.]*(?:,\1\b[\$\w\.]*)*/g
		//match dot
		, dotRe = /\./g
		//match directory separator
		, dsRe = /\//g
		//match text after dot
		, dotsRe = /\.?[^\.]+$/
		//match dot at end
		, dot2dsRe = /\.|$/g
		//match text before comma
		, varsRe = /([^,]+)/g
		//match .js file extension
		, jsExtRe = /\.js$/i
		, scriptBase = $JSI.scriptBase
		//the scriptBase's length
		, pathPos = scriptBase.length
		//延迟任务队列
		, lazyTasks
		, lazyScript = "<scr" + "ipt type='text/javascript' src='" + (this.netscape ? "data:text/javascript,$JSI.runLazyTask()" : $JSI.bootBase + "__res/lazy-trigger.js") + "'></scr" + "ipt>"
		, mappedPath = {}
		, importedStyleMap = {}
		//the prototype for function
		, $p;
	/**
	 * 执行延迟任务，如：无阻塞导入（Non Blocking Import） 不阻塞窗体事件线程的条件下，同步导入预定类 
	 * @private 
	 */
	$JSI.runLazyTask = function()
	{
		if(!lazyTasks)
		{
			return;
		}
		var root = lazyTasks[0];

		if (root instanceof Function)
		{
			root();
		}
		else if (root.start instanceof Function)
		{
			//is task
			if (root instanceof DependenceLoadTask || root instanceof PackageLoadTask)
			{
				return runImportTask(root);//break out
			}
			root.start();
		}

		lazyTasks.length > 1 ? lazyTasks.shift() : lazyTasks = null;
	}
	/**
	 * 包名转换 
	 * @public
	 * @param {string} map 映射名 
	 * @param {string} path 实际路径
	 * @id $JSI.mapPath
	 */
	var mp = $JSI.mapPath = function(map, path)
	{
		mappedPath[map] = path;
		//mappedPath[path] = map;
	}

	mp("YAHOO", "com.yahoo.yui:YAHOO");
	mp("Ext", "com.extjs:Ext");
	mp("jQuery", "com.jquery");
	mp("Prototype", "org.prototypejs");
	mp("Scriptaculous", "org.scriptaculous");

	/**
	 * 包信息数据结构类. 
	 * 在包目录下应该有包初始化脚本（__package__.js），在包的构造中执行这段脚本，执行中，this指向当前包对象 
	 * @public 
	 * @constructor 
	 * @final 
	 * @param {String} pkgName 包名（必须为真实存在的包） 
	 * @param {Function|String} pscript 包定义脚本
	 */
	function Package(pkgName, pscript)
	{
		/**
		 * 注册包
		 */
		packageMap[pkgName] = this;
		////$log.debug("Package建立包对象" + pkgName);
		/**
		 * 包名  
		 * @private 
		 * @readonly 
		 * @typeof string 
		 * @member Package 
		 */
		this.name = pkgName;
		/**
		 * 包脚本路径  
		 * @private 
		 * @readonly 
		 * @typeof string 
		 * @member Package 
		 */
		this.scriptBase = scriptBase + (pkgName.replace(dotRe, "/")) + "/";
		////$log.debug("Package设定包脚本目录" + this.scriptBase);
		/**
		 * 包脚本依赖
		 *   
		 * <pre><code> 
		 * {'thisPath':[{ 
		 *   'type':type. 
		 *   'path':pureTargetPath, 
		 *   'fileName':fileName, 
		 *   'objName':fullObjectName || null, 
		 *   'beforeLoad' : (beforeLoad != false) 
		 * },...]}</code></pre>
		 * 起初作为一个数组对象临时存储 依赖信息。
		 * init成员方法调用后。
		 * 将装还成一个对象、且计算完全部包内匹配
		 * @private 
		 * @readonly 
		 * @typeof object 
		 * @member Package 
		 */
		this.dependenceMap = [];
		/**
		 * 脚本装载器表{scriptPath:ScriptLoader} 
		 * @private 
		 * @readonly 
		 * @typeof object 
		 * @member Package 
		 */
		this.loaderMap = {};
		/**
		 * 脚本->对象表{scriptPath:objName} 
		 * object名为类名或包名 如<code>YAHOO</code> 
		 * @private 
		 * @typeof object 
		 * @readonly 
		 * @member Package 
		 */
		this.scriptObjectMap = {};
		/**
		 * 对象->脚本表{objName:scriptPath} 
		 * object名为全名 如<code>YAHOO.ui.Color</code> 
		 * @private 
		 * @readonly 
		 * @typeof object 
		 * @member Package 
		 */
		this.objectScriptMap = {};
		/**
		 * 存储顶级对象的表. 
		 * 比如yahoo ui 的objectMap = {YAHOO:?} 
		 * prototype 的objectMap = {$:?,$A:? ....} 
		 * @private 
		 * @readonly 
		 * @typeof object 
		 * @member Package 
		 */
		this.objectMap = {};

		try
		{
			////$log.debug("Package执行包定义脚本", pscript);
			if (typeof pscript == "function")
			{
				this.load = pscript;
				this.load();//with(this)eval(load);
			}
			else
			{
				this.load(pscript);
			}
		}
		catch (e)
		{
			$log.error("Package执行包定义失败." + pkgName, e);
			throw e;
		}
		////$log.debug("Package执行包定义成功,初始化包");
		this.init();
		////$log.debug("Package初始化包OK");
	}
	/*
	 * Package method 定义
	 */
	$p = Package.prototype;
	/** 
	 * 执行脚本 
	 * @private
	 * @id Package.prototype.load
	 */
	$p.load = $JSI.$eval;
	/**
	 * 包内脚本加载函数
	 * @id Package.prototype.loadURL
	 * @private
	 * @param {string} fileName 脚本名称
	 * @return {string} 脚本内容
	 */
	$p.loadURL = function(fileName)
	{
		return $JSI.loadURL(this.scriptBase + fileName);
	}

	/**
	 * 初始化包
	 * @id Package.prototype.init
	 * @private
	 */
	$p.init = function()
	{
		/*
		 * 依赖设置说明： 
		 * 对于对象的依赖，先看看本包中是否有匹配，有，目标包就是本包，马上初始化 
		 * 对于脚本依赖，有/则说明不是本包。若本包马上初始化 
		 * 对于本包，且（匹配式路径 或 匹配方式对象） 
		 * 需要剔除对本身脚本的依赖。 
		 */
		var depMap = this.dependenceMap
			, objScriptMap = this.objectScriptMap
			, map = {}
			, i = depMap.length - 1
			, flagRe = /[:\*]/g
			, nameRe = /^.*:([\$\w]+).*$/
			, dotRs = /[\.]/g;
			//$log.debug("Package.init包内依赖定义" + this.name, depMap);
		for (; i >= 0; i--)
		{
			var depInfo = new DependenceInfo
				, dep = depMap[i]
				, type = dep[0]
				, key = dep[1]
				, target = dep[2]
				, beforeLoad = depInfo.beforeLoad = (dep[3] === false ? false : true)
				, flags = target.match(flagRe)
				, file
				, objName
				, keyIsArray = key instanceof Array
				, j = key.length - 1
				, pos
				, mPath;
				if(type < 3 && (pos = target.indexOf(".")) > 0 && !objScriptMap[target] && (mPath = mappedPath[target.substring(0, pos)]))
				{
					target = mPath + target.substr(pos);//处理类似YAHOO.util.Dom的对象时
				}
			if (flags)
			{
				if(flags.pop() == ":" && !beforeLoad && key != "*")
				{
					depInfo.names = [target.replace(nameRe, "$1")];
					depInfo.getNames = getStaticNames;
				}
				else 
				{
					if(target == "*")
					{//依赖当前包其他全部脚本。
						depInfo.getNames = getExcludeName;
					}
					else
					{//依赖其他包脚本对象
						target = (pos = target.indexOf(":")) > 0 ? target.substring(0, pos).replace(dotRs, "/") + target.substr(pos) : target.replace(dotRs, "/");
					}
					type = type | 1;
				}
			}

			if (type & 1)
			{
				//01,11 file
				depInfo.init = fileDependenceInit;
				depInfo.load = fileDependenceLoader;
			}
			depInfo.id = uid++;
			depInfo.pkg1 = this;
			depInfo.target = target;

			if (key == "*")
			{
				//the  same package  :getExcludeName
				if (flags = target instanceof Array)
				{
					target = target[0];
				}
				if (type & 1)
				{
					//11,01
					//if (target.indexOf("/") > 0)
					if (target.indexOf("/") > -1)
					{
						//外包
						target = null;
					}
				}
				else
				{
					//10,00
					target = objScriptMap[target];  //本包 not null
				}
				if (target)
				{
					//$log.debug("Package.init依赖脚本目标" + this.name, target);
					depInfo.getNames = getExcludeName;
				}
				for (key in this.scriptObjectMap)
				{
					if (flags || key != target)
					{
						(map[key] || (map[key] = [])).push(depInfo);
						////$log.debug("Package.init添加*脚本-脚本依赖" + key + "->" + depInfo.target);						
					}
				}
			}
			else if (type < 2)
			{
				//00,01
				if (beforeLoad)
				{
					if (keyIsArray)
					{
						flags = {};
						for (; j >= 0; j--)
						{
							file = objScriptMap[key[j]];
							if (flags[file] != true)
							{
								flags[file] = true;
								(map[file] || (map[file] = [])).push(depInfo);
								////$log.debug("Package.init添加[]对象-对象前置依赖" + key + "->" + depInfo.target);
							}
						}
					}
					else
					{
						file = objScriptMap[key];
						(map[file] || (map[file] = [])).push(depInfo);
						////$log.debug("Package.init添加对象-对象前置依赖" + key + "->" + depInfo.target);
					}
				}
				else
				{
					if (keyIsArray)
					{
						for (; j >= 0; j--)
						{
							file = objScriptMap[objName = key[j]];
							(map[file] || (map[file] = [])).push([objName, depInfo]);
							////$log.debug("Package.init添加[]对象-对象后置依赖" + file + "->" + depInfo.target);
						}
					}
					else
					{
						file = objScriptMap[key];
						(map[file] || (map[file] = [])).push([key, depInfo]);
						////$log.debug("Package.init添加对象-对象后置依赖" + key + "->" + depInfo.target);
					}
				}
			}
			else
			{
				if (keyIsArray)
				{
					for (; j >= 0; j--)
					{
						file = key[j];
						(map[file] || (map[file] = [])).push(depInfo); 
						////$log.debug("Package.init添加[]脚本-脚本依赖" + file + "->" + depInfo.target);
					}
				}
				else
				{
					(map[key] || (map[key] = [])).push(depInfo);
					////$log.debug("Package.init添加脚本-脚本依赖" + key + "->" + depInfo.target);
				}
			}
		}
		////$log.debug("Package.init得到脚本依赖集合["+this.name+"]", map);
		this.dependenceMap = map;
	}

	/**
	 * 添加脚本及其声明的对象（函数、方法名）。 
	 * 需要指定脚本位置（必须在当前包目录中），元素名(可用数组，同时指定多个)。 
	 * <i>该成员函数只在包定义文件（__package__.js）中调用 </i> 
	 * @public
	 * @id Package.prototype.addScript
	 * @param {string} scriptPath 指定脚本路径 
	 * @param {string|Array} objNames 对象名称字符串或其数组 
	 */
	$p.S = $p.addScript = function(scriptPath, objNames, beforeLoadDependences, afterLoadDependences)
	{
		var scriptObjMap = this.scriptObjectMap[scriptPath] || (this.scriptObjectMap[scriptPath] = [])
			, dotBeforeRe = /\..*$/
			, objName
			, i;

		//empty script 
		if (!objNames || (i = objNames.length - 1) < 0)
		{
			return $log.info("Package添加了空脚本" + scriptPath);
		}
		if (!(objNames instanceof Array))
		{
			objNames = [objNames];
			i = 0;
		}
		for (; i >= 0; i--)
		{
			objName = objNames[i];
			this.objectScriptMap[objName] = scriptPath;
			objName = objName.replace(dotBeforeRe, "");
			scriptObjMap.push(objName);
		}
		beforeLoadDependences && this.addDependence(scriptPath, beforeLoadDependences, true);
		afterLoadDependences && this.addDependence(scriptPath, afterLoadDependences, false);
	}
	/**
	 * 添加脚本依赖。 
	 * 将根据路径确定thisPath 和 targetPath的类型：文件？对象； 
	 * 再调用具体函数，添加对应依赖 
	 * <i>该成员函数只在包定义文件（__package__.js）中调用 </i> 
	 * @public
	 * @id Package.prototype.addDependence
	 * @param {String} thisPath 本包中当前脚本。 
	 * @param {String} targetPath 依赖的脚本 
	 * @param {Boolean} [beforeLoad=true] 可选参数(默认为true) 是否需要执行前导入(装载期依赖)
	 */
	$p.D = $p.addDependence = function(thisPath, targetPath, beforeLoad)
	{
		var type =  jsExtRe.test(thisPath) ? 2 : 0;
		if(!(targetPath instanceof Array))
		{
			targetPath = [targetPath];
		}
		var i = targetPath.length;
		while(i--)
		{
			this.dependenceMap.push([type + (jsExtRe.test(targetPath[i]) ? 1 : 0), thisPath, targetPath[i], beforeLoad]);
		}
	}

	/**
	 * 设置具体实现包名。
	 * 比如，我们可以给prototype库一个统一的包， 
	 * 但是我们的内容都放在具体的实现版本里， 
	 * 我们可以通过该设置（setImplementation(this.name + ".v1.5");）来指定默认的具体实现版本。 
	 * <i>该成员函数只在包定义文件（__package__.js）中调用 </i>
	 * @id Package.prototype.setImplementation
	 * @public
	 * @param {String} pkgPath 指定实现包名，全路径(ID(.ID)*)或相对路径（"." 开始的为本包下的相对路径） 
	 */
	$p.I = $p.setImplementation = function(pkgPath)
	{
		var dotPathRe = /\w+\.\.\.\//;
		if (pkgPath.charAt(0) == ".")
		{
			if (pkgPath.charAt(1) == ".")
			{
				pkgPath = this.name + "." + pkgPath;
				while (pkgPath.length > (pkgPath = pkgPath.replace(dotPathRe, "")).length);
			}
			else
			{
				pkgPath = this.name + pkgPath; 
			}
		}
		this.implementation = pkgPath;
	}

	/**
	 * 加载指定脚本对象,若加载器不存在则创建一个新的类加载器
	 * @id Package.prototype.loadScript
	 * @private 
	 * @param {String} fileName 指定的脚本文件名 
	 * @param {String} objName 需要装载的对象 * 代表全部元素 
	 */
	$p.loadScript = function(fileName, objName)
	{
		var loader = this.loaderMap[fileName];

		if (!loader)
		{
			//$log.debug("Package.loadScript加载脚本文件:", this.scriptBase + fileName);
			if (this.scriptObjectMap[fileName])
			{
				try
				{
					//$log.debug("Package.loadScript建立脚本加载对象:" + fileName, this.scriptBase + fileName);
					loader = new ScriptLoader(this, fileName);
					////$log.debug("Package.loadScript建立脚本加载对象OK", loader);
				}
				catch (e)
				{
					return $log.error("Package.loadScript加载对象失败" + this.name + "." + objName, e);
					//throw e;
				}
			}
			else
			{
				return $log.error("Package.loadScript未找到对象定义" + this.name + "." + objName);
				//TODO: try parent
				//throw new Error("Package.loadScript未找到脚本文件！");
			}
		}
		if (objName && loader.init)
		{
			////$log.debug("Package.loadScript加载脚本对象OK:" + this.name + "." + objName);
			//$log.debug("Package.loadScript初始化脚本对象:" + this.name + "." + objName);
			loader.init(objName);
			////$log.debug("Package.loadScript初始化脚本对象OK:" + this.name + "." + objName);
		}
	}

	/**
	 * 脚本装载器. 
	 * @constructor 
	 * @protected 
	 * @implicit 
	 * @param {Package} pkg 包对象 
	 * @param {string} fileName 脚本名  
	 */
	function ScriptLoader(pkg, fileName)
	{
		/**
		 * 脚本名，可在托管脚本顶层上下文（非函数内）访问，<code>this&#46;name</code> 
		 * @friend 
		 * @owner ScriptLoader 
		 * @typeof string
		 */
		this.name = fileName;
		/**
		 * 包名，可在托管脚本顶层上下文（非函数内）访问，<code>this&#46;packageName</code> 
		 * @friend 
		 * @owner ScriptLoader 
		 * @typeof string  
		 */
		this.packageName = pkg.name;
		/**
		 * 脚本目录，可在托管脚本顶层上下文（非函数内）访问，<code>this&#46;scriptBase</code> 
		 * @friend 
		 * @owner ScriptLoader 
		 * @typeof string  
		 */
		this.scriptBase = pkg.scriptBase;
		////$log.debug("ScriptLoader建立脚本加载器对象:[" + pkg.name + "]" + this.name);
		var loader = this.beforeLoad();
		if (loader)
		{
			////$log.debug("ScriptLoader.beforeLoad加载前操作完成");
			return loader;
		}
		this.load(pkg);

		var ns = pkg.scriptObjectMap[fileName]
			, i = ns.length
			, objMap = pkg.objectMap
			, values;
		if (i == 1)
		{
			ns = ns[0];
			objMap[ns] = this.hook(ns);
		}
		else
		{
			values = this.hook("[" + ns.join(",") + "]"); 
			while (i-- > 0)
			{
				objMap[ns[i]] = values[i];
			}
		}
	}

	$p = ScriptLoader.prototype;
	/**
	 * 前期准备，包括依赖变量申明，装载前依赖的装载注入
	 * @id ScriptLoader.prototype.beforeLoad
	 * @private
	 */
	$p.beforeLoad = function()
	{
		//这个时候肯定已经有了包 
		var pkg = packageMap[this.packageName]
			, vars = ["$log"]
			, name = this.name
			, deps = pkg.dependenceMap[name]//load before dep
			, dep
			, depMap
			, depName
			, i;
		////$log.debug("ScriptLoader.beforeLoad分析脚本依赖对象" + name, deps);
		vars.$log = $JSI.buildLog(pkg.name.replace(dot2dsRe, "/") + name);//初始化log
		if (deps != null)
		{
			for (i = deps.length - 1; i >= 0; i--)
			{
				dep = deps[i];
				vars.push.apply(vars, (dep[1] || dep).getNames(name));
				/*var varNames = {}, j = vars.length - 1;
				for(; j >= 0; j--)
				{
					if(varNames[vars[j]])
					{
						vars.splice(j, 1);
					}
					else
					{
						varNames[vars[j]] = true;					
					}
				}//*/
				//$log.debug("ScriptLoader.beforeLoad添加依赖变量" + name + ":" + (dep[1] || dep).getNames(name));
				//if(beloaded by before load dependence , return it); 
				if (dep.beforeLoad)
				{
					dep.load(vars, name);
					//$log.debug("ScriptLoader.beforeLoad前置装载依赖变量" + name + ":" + vars);
					if (dep = pkg.loaderMap[name])
					{
						//$log.debug("ScriptLoader.beforeLoad已加载过" + pkg.name + ":" + name);
						return dep;
					}
				}
				else if (dep instanceof Array)
				{
					depMap = this.dependenceMap;
					depName = dep[0];
					//$log.debug("ScriptLoader.beforeLoad检测依赖" + name + ":" + depName, dep[1]);
					depMap ? depMap[depName] ? depMap[depName].push(dep[1]) : depMap[depName] = [dep[1]] : (this.dependenceMap = {})[depName] = [dep[1]];
				}
				else
				{
					this.dependenceList ? this.dependenceList.push(dep) : this.dependenceList = [dep];
				}
			}
		}
		pkg.loaderMap[name] = this;

		this.varText = "var " + vars.join(",").replace(varsRe, "$1 = this.vars.$1");
		//$log.debug("ScriptLoader.beforeLoad生成变量列表" + name + ":" + vars);
		this.vars = vars;
	}
	/**
	 * 初始化制定对象，*代表全部对象，即当前装载单元的全部对象
	 * @private
	 * @id ScriptLoader.prototype.init
	 * @param {String} objName 对象名称
	 */
	$p.init = function(objName)
	{
		var vars = []
			, name = this.name
			, deps = this.dependenceList
			, depMap = this.dependenceMap
			, i = 0
			, dep;
		if (deps)
		{
			this.dependenceList = null;
			for (i = deps.length - 1; i >= 0; i--)
			{
				dep = deps[i];
				vars.push.apply(vars, dep.getNames(name));
				//$log.debug("ScriptLoader.init加载脚本-变量依赖" + name, vars);
				dep.load(vars, name);
			}
		}

		if (depMap)
		{
			var hitAll = true;
			//这里进行了展开优化，有点冗余
			if (objName == "*")
			{
				for (objName in depMap)
				{
					deps = depMap[objName];
					/*if (!deps)
					{
						$log.info("ScriptLoader.init未找到依赖描述" + objName);
						continue;
					}*/
					for (i = deps.length - 1; i >= 0; i--)
					{
						dep = deps[i];
						vars.push.apply(vars, dep.getNames(name));
						dep.load(vars, name);
						//$log.debug("ScriptLoader.init加载对象-对象依赖" + name, vars);
					}
				}
				this.dependenceMap = null;
				//不能delete
				this.init = null;
			}
			else
			{
				if (deps = depMap[objName])
				{
					delete depMap[objName];//must delete at first,otherwise cause circular
					for (i = deps.length - 1; i >= 0; i--)
					{
						dep = deps[i];
						vars.push.apply(vars, dep.getNames(name));
						////$log.debug("ScriptLoader.init加载脚本-脚本|对象依赖" + name, vars, dep);
						dep.load(vars, name);
					}
				}
				for (objName in depMap)
				{
					hitAll = false; break;
				}
				if (hitAll)
				{
					this.dependenceMap = null;
					this.init = null;
				}
			}
		}
		else
		{
			this.init = null;
		}
		if (vars.length)
		{
			this.vars = vars;
			vars = vars.join(",");
			//$log.debug("ScriptLoader.init得到预加载变量列表", vars);
			this.hook(vars.replace(varsRe, "$1 = this.vars.$1"));
			this.vars = null;
		}
	}

	/**
	 * 脚本加载及执行
	 * @id ScriptLoader.prototype.load
	 * @private
	 * @param {Package} pkg 包对象
	 */
	$p.load = function(pkg)
	{
		var script = $JSI.getCacheScript(pkg.name, this.name);
		try
		{
			if (typeof script == "function")
			{
				this.doLoad = script;
				$JSI.addCacheScript(pkg.name, this.name, null);//clear cache
				return this.doLoad();
			}
			else
			{
				return this.doLoad(script || pkg.loadURL(this.name)); 
			}
		}
		catch (e)
		{
			$log.error("ScriptLoader.load执行脚本错误", this.scriptBase + this.name, e);
			//throw e;
		}
		finally
		{
			this.vars = null;
		}
	}

	/**
	 * 执行加载过程
	 * @id ScriptLoader.prototype.doLoad
	 * @private 
	 */
	$p.doLoad = arguments[0];
 
	/**
	 * 任务队列，异步装载实现
	 * @public
	 * @param {boolean} [init=false] 是否初始化
	 * @return {TaskQueue}
	 * @constructor
	 */
	function TaskQueue(init)
	{
		if(init)
			this.init();
	}

	$p = TaskQueue.prototype;
	/**
	 * 初始化TaskQueue
	 * @id TaskQueue.prototype.init
	 * @private
	 */
	$p.init = function()
	{
		/**
		 * 任务队列  
		 * @private 
		 * @readonly 
		 * @typeof array 
		 * @member TaskQueue 
		 */
		this.queue = [];
		/**
		 * 队列索引  
		 * @private 
		 * @readonly 
		 * @typeof number 
		 * @member TaskQueue 
		 */
		this.index = 0;

		/**
		 * 运行状态.-1:初始状态,0:正常运行,1:挂起状态,2:失败,3:成功  
		 * @private 
		 * @readonly 
		 * @typeof number 
		 * @member TaskQueue 
		 */
		this.state =  - 1;

		this._next = false;
		/**
		 * 任务运行间隔时间
		 * @private 
		 * @readonly 
		 * @typeof number
		 * @member TaskQueue 
		 */
		this.waitTime = 1;
		this.failureList = [];
		this.listenersMap = {};
	}


 
	/**
	 * 开始任务
	 * @id TaskQueue.prototype.start
	 * @public
	 */
	$p.start = function()
	{

		if (this.state >= 0)
		{
			return;
		}
		this.state = 0;
		this.fireEvent("start");

		if (!this.isFinished())
		{
			this._next = true;
			this.resume();
		}
		else
		{
			this.fireEvent("success");
			this.fireEvent("finish");
		}
	}

	/**
	 * 挂起任务
	 * @id TaskQueue.prototype.suspend
	 * @public
	 */
	$p.suspend = function()
	{
		this.state == 0 ? this.state = 1 : $log.info("TaskQueue.suspend任务未被挂起,当前状态" + this.state);
	}

	/**
	 * 唤醒任务
	 * @id TaskQueue.prototype.resume
	 * @public
	 */
	$p.resume = function()
	{
		var queue = this;
		if (this.state == 1)
		{
			this.state = 0;
			if (this._next && this.checkState())
			{
				setTimeout(function()
				{
					queue.resume();
				}, 0);
			}
		}
		else if (this._next)
		{
			this._next = false;

			var task = this.queue[this.index], flag = task instanceof TaskQueue;
			if (flag)
			{
				this.suspend(); //挂起状态
				task.start();
			}
			try
			{
				if(!flag)
				{
					// 执行任务
					task.apply(this);
				}
			}
			catch (e)
			{
				this.failureList.push(this.index);
				$log.error("TaskQueue.resume唤醒任务执行失败", e);//throw e;
			}
			finally
			{
				this.index++;
				if (this.state == 0)
				{
					if (this.checkState())
					{
						setTimeout(function()
						{
							queue.resume();
						}, this.waitTime);
					}
				}
				this._next = true;
			}
		}
	}

	/**
	 * 检查任务队列运行状态.根据当前状态触发事件
	 * @id TaskQueue.prototype.checkState
	 * @private
	 */
	$p.checkState = function()
	{
		if (this.isFinished())
		{
			if (this.failureList.length)
			{
				this.state = 2;
				this.fireEvent("failure");
			}
			else
			{
				this.state = 3;
				this.fireEvent("success");
			}
			this.fireEvent("finish");
			//this.init();//重置为初始状态
			if (this.parentTask)
			{
				this.parentTask.resume();
			}
			return false;
		}
		else
		{
			this.fireEvent("step");
			return true;
		}
	}
	/**
	 * 检查任务队列是否顺序执行完毕
	 * @id TaskQueue.prototype.isFinished
	 * @public
	 * @return {boolean} 完成返回<code>true</code>,否则返回<code>false</code>
	 */
	$p.isFinished = function()
	{
		return this.index >= this.queue.length;
	}
	/**
	 * 事件触发器.根据事件名称执行对应的事件定义
	 * @id TaskQueue.prototype.fireEvent
	 * @private
	 */
	$p.fireEvent = function(ev)
	{
		var listeners = this.listenersMap[ev];
		if (listeners)
		{
			for (var i = 0, len = listeners.length; i < len; i++)
			{
				listeners[i].apply(this);
			}
		}
	}
	/**
	 * 添加任务到队列.
	 * @id TaskQueue.prototype.addTask
	 * @public
	 * @param {function|TaskQueue} task 任务定义
	 * @param {number} [index] 要插入的位置，默认插入到最末
	 */
	$p.addTask = function(task, index)
	{
		if (task instanceof TaskQueue)
		{
			task.parentTask = this;
		}
		else if (!(task instanceof Function))
		{
			return $log.error("TaskQueue.addTask任务应是函数或TaskQueue的实例" + task);
			//throw new Error("task must be a function or TaskQueue instance, but not:" + task);
		}
		typeof index == "number" ? this.queue.splice(index, 0, task) : this.queue.push(task);
	}
	/*
	 * 构造TaskQueue的Listener方法
	 * @param {String} ev
	 */
	function buildTaskQueuePrototype(ev)//buildTaskQueuePrototype
	{
		var evName = ev + "Listener";
		ev = ev.toLowerCase();
		$p["add" + evName] = function(listener)
		{
			this.listenersMap[ev] ? this.listenersMap[ev].push(listener) : this.listenersMap[ev] = [listener];
		}
		$p["remove" + evName] = function(listener)
		{
			for (var list = this.listenersMap[ev]
				, i = list.length - 1; i >= 0; i--)
			{
				if (list[i] == listener)
				{
					list.splice(i, 1);
				}
			}
		}
		evName = null;
	}

	for (var taskEvents = ["Start", "Step", "Success", "Failure", "Finish"], taskEventsLen = taskEvents.length - 1; taskEventsLen >= 0; taskEventsLen--)
	{
		buildTaskQueuePrototype(taskEvents[taskEventsLen]);
	}
	
	/**
	 * 添加失败事件处理器
	 * @id TaskQueue.prototype.addFailureListener
	 * @public
	 * @param {function} listener 事件处理器
	 */
	/**
	 * 添加运行事件处理器
	 * @id TaskQueue.prototype.addStepListener
	 * @public
	 * @param {function} listener 事件处理器
	 */
	/**
	 * 添加成功事件处理器
	 * @id TaskQueue.prototype.addSuccessListener
	 * @public
	 * @param {function} listener 事件处理器
	 */
	/**
	 * 添加开始事件处理器
	 * @id TaskQueue.prototype.addStartListener
	 * @public
	 * @param {function} listener 事件处理器
	 */
	/**
	 * 添加完成事件处理器
	 * @id TaskQueue.prototype.addFinishListener
	 * @public
	 * @param {function} listener 事件处理器
	 */
	/**
	 * 移除指定的失败事件处理器
	 * @id TaskQueue.prototype.removeFailureListener
	 * @public
	 * @param {function} listener 事件处理器
	 */
	/**
	 * 移除指定的运行事件处理器
	 * @id TaskQueue.prototype.removeStepListener
	 * @public
	 * @param {function} listener 事件处理器
	 */
	/**
	 * 移除指定的成功事件处理器
	 * @id TaskQueue.prototype.removeSuccessListener
	 * @public
	 * @param {function} listener 事件处理器
	 */
	/**
	 * 移除指定的开始事件处理器
	 * @id TaskQueue.prototype.removeStartListener
	 * @public
	 * @param {function} listener 事件处理器
	 */
	/**
	 * 移除指定的完成事件处理器
	 * @id TaskQueue.prototype.removeFinishListener
	 * @public
	 * @param {function} listener 事件处理器
	 */	
	/**
	 * 文件加载任务队列
	 * @abstract
	 * @param {array} urlList 地址序列
	 * @extend TaskQueue
	 * @constructor
	 */
	function LoadTask(urlList)
	{
		this.init();
		this.urlList = urlList;
		this.addTask(loadExec);
	}
	extend(LoadTask, TaskQueue);
	/**
	 * 任务绑定操作
	 * @public
	 * @param {TaskQueue} task 任务对象
	 * @param {Array} urls 地址序列
	 */
	LoadTask.bind = function(task, urls)
	{
		task.suspend();
		var index = 0;
		return function _()
		{
			var url = urls[index++];
			if (url)
			{
				if(task instanceof PackageLoadTask && task.name != needLoadedPackage(task.name))
				{
					return _();
				}
				try
				{
					$JSI.loadURL(url, function(req)
					{
						if (req.readyState == 4)
						{
							var stus = req.status,
								result = null;
							if (stus >= 200 && stus < 300 || stus == 304 || !stus)
							{
								result = req.responseText;
							}
							req = null;
							task.accept(url, result);
							_();
						}
					});
				}
				catch (e)
				{
					task.accept(url, null);
					task.resume();
					$log.error("LoadTask:bind加载文件失败" + url, e);//throw e;
				}
			}
			else
			{
				task.resume();
			}
		}
	}

	function DependenceLoadTask(dep, scheduleMap)
	{
		scheduleMap[dep.id] = true;
		//初始化任务队列 
		this.init();
		this.dependence = dep;
		this.scheduleMap = scheduleMap;
		//装载目标包
		if (!dep.scriptObjectMap)
		{
			var path = dep.target
				, pos;
			if (path instanceof Array)
			{
				path = path[0];
			}
			
			pos = path.indexOf(":");
			
			if (dep.load == fileDependenceLoader)
			{
				
				path = pos > -1 ? path.substr(0, pos).replace(dsRe, ".") : path.substr(0, path.lastIndexOf("/")).replace(dsRe, ".");
			}
			else
			{

				path = pos > -1 ? path.substr(0, pos) : dep.pkg1.objectScriptMap[path] ? 0 : path.substr(0, path.lastIndexOf("."));
			}

			if (path && (path = needLoadedPackage(path)))
			{
				this.addTask(new PackageLoadTask(path)); 
			}
		}
		//初始化装载信息
		this.addTask(dependenceInit);
	}

	extend(DependenceLoadTask, TaskQueue);

	function FileLoadTask(list)
	{
		this.urlList = list;
	}

	$p = extend(FileLoadTask, LoadTask);

	$p.accept = function(url, result)
	{
		url = url.substr(pathPos).split("/");
		var file = url.pop();
		$JSI.addCacheScript(url.join("."), file, result);
	}

	function PackageLoadTask(name)
	{
		this.name = name;
		this.urlList = [scriptBase + (this.name.replace(dotRe, "/")) + "/__package__.js"];
	}

	$p = extend(PackageLoadTask, LoadTask);

	$p.accept = function(path, result)
	{
		var name = this.name;
		if (result)
		{
			if (!packageMap[name])
			{
				new Package(name, result);
			}
		}
		else
		{
			packageMap[name] = null;
		}

		name = needLoadedPackage(name);

		if (name)
		{
			this.urlList.push(scriptBase + ((this.name = name).replace(dotRe, "/")) + "/__package__.js"); 
		}
	}

	function DependenceInfo(){}
	/*
	 * for object 依赖没有* 匹配 
	 * @private 
	 */
	$p = DependenceInfo.prototype;

	/**
	 * DependenceInfo.prototype.init
	 */
	$p.init = function()
	{
		var target = this.target
			, scriptObjMap = this.scriptObjectMap = {}
			, objScriptMap = this.pkg1.objectScriptMap
			, pkg;
		if (target instanceof Array)//_is(target, Array)
		{
			var targetNum = target.length - 1
			, i = targetNum;
			if (objScriptMap[target[0]])
			{
				this.pkg2 = this.pkg1; 
			}
			else
			{
				pkg = findObjectPackage(target[0])
				if(!pkg)
				{
					return $log.error("DependenceInfo.init未找到依赖文件定义" + target[0]);
				}

				this.pkg2 = requirePackage(pkg = pkg.name);

				pkg = pkg.length + 1;

				for (; i >= 0; i--)
				{
					target[i] = target[i].substr(pkg);
				}
			}
			objScriptMap = this.pkg2.objectScriptMap;
			for (i = targetNum; i >= 0; i--)
			{
				var objName = target[i]
					, file = objScriptMap[objName];
				scriptObjMap[file] ? objName.push(target) : scriptObjMap[file] = [target];
			}
		}
		else
		{
			if (objScriptMap[target])
			{
				this.pkg2 = this.pkg1;
			}
			else
			{
				target = mappedPath[target] || target;
				if (pkg = findObjectPackage(target))
				{
					this.pkg2 = requirePackage(pkg = pkg.name);

					target = target.substr((mappedPath[pkg] || pkg).length + 1);
				}
				else
				{
					$log.error("DependenceInfo.init未找到包文件定义" + target); 
				}
			}
			scriptObjMap[this.pkg2.objectScriptMap[target]] = this.target =	[target];
		}
		//$log.debug("DependenceInfo.init文件依赖定义" + target, scriptObjMap);
		this.init = null;
	}
	/**
	 * DependenceInfo.prototype.getNames
	 */
	$p.getNames = function()
	{
		////$log.debug("DependenceInfo.getNames依赖变量加载初始化[" + this.target + "]");
		//if(!this.init)//$log.debug("DependenceInfo.getNames依赖变量初始化操作已经被执行过[" + this.target + "]");
		this.init && this.init();
		//if(this.init)//$log.debug("DependenceInfo.getNames依赖变量初始化完成[" + this.target + "]");
		var scriptObjMap = this.scriptObjectMap
			, names = [];
		if (fileDependenceLoader == this.load)
		{
			var target = this.target, pos = target.indexOf(":");

			if(pos > 0 && target.charAt(target.length -1) != "*")
			{
				target = target.substr(pos + 1);
				names.push((pos = target.indexOf(".")) < 0 ? target : target.substring(0, pos));			
			}		
			else
			{
				for (var oName in scriptObjMap)
				{
					names.push.apply(names, this.pkg2.scriptObjectMap[oName]);
				}
			}
		}
		else
		{
			names = this.target.join(",");
			names = names.indexOf(".") > 0 ? names.replace(nsRe, "$1").split(",") : [this.target];
		}
		/*for(var i = names.length - 1, oName, oNames = {}; i>= 0; i--)
		{
			if(oNames[oName = names[i]])
			{
				names.splice(i, 1);
				//i--;don't use it here
			}
			oNames[oName] = true;
		}*/

		//$log.debug("DependenceInfo.getNames找到依赖变量" + names);
		this.getNames = getStaticNames;
		return this.names = names;
	}

	/**
	 * DependenceInfo.prototype.load
	 * @param {object} vars 变量名
	 * @param {string} exclude 排除的名称
	 * for object 
	 */
	$p.load = function(vars, exclude)
	{
		//for lazy :
		////$log.debug("DependenceInfo.load初始化[" + this.target + "]");
		//if(!this.init)//$log.debug("DependenceInfo.load初始化操作已经被执行过[" + this.target + "]");
		this.init && this.init();
		//if(this.init)//$log.debug("DependenceInfo.load延迟加载初始化完成[" + this.target + "]");
		var scriptObjMap = this.scriptObjectMap
			, objNames
			, objName
			, objMap
			, i
			, file;
		for (file in scriptObjMap)
		{
			if (file == exclude && this.getNames == getExcludeName)
			{
				//same file and same packge and * pattern
				continue;
			}
			objNames = scriptObjMap[file];
			for (i = objNames.length - 1; i >= 0; i--)
			{
				//$log.debug("DependenceInfo.load加载依赖脚本" + this.target, file);
				this.pkg2.loadScript(file, objNames[i]);
			}
		}
		objMap = this.pkg2.objectMap;
		objNames = this.getNames(exclude);
		//$log.debug("DependenceInfo.load得到加载对象列表" + this.target, objNames);
		for (i = objNames.length - 1; i >= 0; i--)
		{
			objName = objNames[i];
			vars[objName] = objMap[objName];
		}
		//$log.debug("DependenceInfo.load得到对象依赖变量" + this.target, vars);
	}

	$p = mp = buildTaskQueuePrototype = taskEvents = taskEventsLen = null;

	$JSI.addCacheScript("org.xidea.util", "task.js", function(){this.hook = function(){return [TaskQueue,LoadTask];}});
	//$JSI.addCacheScript("js.lang", "package.js", function(){this.hook = function(){return [Package];}});

	function extend(c, p)
	{
		c.prototype = new p;
		c.prototype.constructor = c;
		return c.prototype;
	}
	function loadExec()
	{
		LoadTask.bind(this, this.urlList)();
	}
	function needLoadedPackage(name)
	{
		do
		{
			if (packageMap[name] || $JSI.getCacheScript(name))
			{
				var pkg = findPackage(name, true);
				if (pkg.implementation)
				{
					name = pkg.implementation;
					continue;
				}
				//$log.debug("needLoadedPackage不需加载包定义文件：" + name);
				return null;
			}
			if (packageMap[name] === undefined)
			{
				//$log.debug("needLoadedPackage需要加载包定义文件：" + name);
				return name;
			}
			name = name.substr(0, name.lastIndexOf("."));
		}
		while (name);
	}
	/*
	 * DependenceInfo.prototype.init 
	 * @private 
	 */
	function fileDependenceInit()
	{
		var target = this.target
			, scriptObjMap = this.scriptObjectMap = {}
			, pos
			, i;
		if (target instanceof Array)
		{
			pos = target[0].lastIndexOf("/");
			i = target.length - 1;
			if(pos > -1)
			{
				this.pkg2 = requirePackage(target[0].substring(0, pos++).replace(dsRe, "."));
				for (; i >= 0; i--)
				{
					scriptObjMap[target[i].substr(pos)] = [];
				}
			}
			else
			{
				this.pkg2 = this.pkg1;
				for (; i >= 0; i--)
				{
					scriptObjMap[target[i]] = []; 
				}
			}
		}
		else
		{
			pos = target.lastIndexOf(":");
			if(pos <= -1)
			{
				pos = target.lastIndexOf("/");
			}
			//if (pos > -1)
			if (pos > 0)
			{
				this.pkg2 = requirePackage(target.substring(0, pos++).replace(dsRe, "."));
				target = target.substr(pos).replace(dsRe, ".");
				target = target;
			}
			else
			{
				this.pkg2 = this.pkg1;
			}
		
			if (target == "*")
			{
				for (target in this.pkg2.scriptObjectMap)
				{
					scriptObjMap[target] = [];// no this here before
				}
			}
			else
			{
				var objScriptMap2 = this.pkg2.objectScriptMap
					, oName
					, objScriptFile;
				if(target.charAt(pos = target.length - 1) == "*")
				{
					//处理类似YAHOO.util.*这样的格式
					target = target.substr(0, pos - 1);//skip .

					for(oName in objScriptMap2)
					{
						if(oName.indexOf(target) == 0 && !scriptObjMap[objScriptFile = objScriptMap2[oName]])
						{
							scriptObjMap[objScriptFile] = [];
						}	
					}
				}
				else if(objScriptFile = objScriptMap2[target])//包对象
				{
					scriptObjMap[objScriptFile]=[];
				}
				else 
					scriptObjMap[target] = [];
			}
		}
		//$log.debug("DependenceInfo.init:fileDependenceInit文件依赖定义" + target, scriptObjMap);
		this.init = null;
	}

	/*
	 * DependenceInfo.prototype.load
	 */
	function fileDependenceLoader(vars, exclude)
	{
		for (var file in this.scriptObjectMap)
		{
			if (file == exclude && this.getNames == getExcludeName)
			{
				//same file and same packge and * pattern
				continue;
			}
			//$log.debug("DependenceInfo.init:fileDependenceLoader加载依赖脚本" + file);
			this.pkg2.loadScript(file, "*");
		}

		for (var objMap = this.pkg2.objectMap
				, objNames = this.getNames(exclude)
				, i = objNames.length - 1
				, objName; i >= 0; i--)
		{
			objName = objNames[i];
			vars[objName] = objMap[objName];
		}
		//$log.debug("DependenceInfo.init:fileDependenceLoader得到加载对象列表" + objNames);//, vars
	}

	/*
	 * DependenceInfo.prototype.getNames
	 */
	function getStaticNames()
	{
		return this.names;
	}
	/*
	 * DependenceInfo.prototype.getExcludeName
	 */
	function getExcludeName(file)
	{
		var scriptObjMap = this.scriptObjectMap || this.init() || this.scriptObjectMap
			, scriptObjMap2 = this.pkg2.scriptObjectMap
			, names = []
			, name
			, exclude = scriptObjMap[file]
			, flag;
		if (exclude)
		{
			if (exclude.names)
			{
				//$log.debug("DependenceInfo.getNames:getExcludeName找到依赖变量" + names);
				return exclude.names;
			}
			if (flag = fileDependenceLoader != this.load)
			{
				scriptObjMap2 = scriptObjMap;
			}
			for (name in scriptObjMap)
			{
				if (name != file)
				{
					names.push.apply(names, scriptObjMap2[name]);
				}
			}
			if (flag && (name = names.join(",")).indexOf(".") > 0)
			{
				names = name.replace(nsRe, "$1").split(",");
			}

			//$log.debug("DependenceInfo.getNames:getExcludeName找到依赖变量" + names);
			return exclude.names = names;
		}
		else if (this.names)
		{
			//$log.debug("DependenceInfo.getNames:getExcludeName找到依赖变量" + this.names);
			return this.names;
		}
		else
		{
			if (fileDependenceLoader == this.load)
			{
				for (name in scriptObjMap)
				{
					names.push.apply(names, scriptObjMap2[name]);
				}
			}
			else
			{
				names = this.target.join(",");
				names = names.indexOf(".") > 0 ? names.replace(nsRe, "$1").split(",") : [this.target];
			}
			//$log.debug("DependenceInfo.getNames:getExcludeName找到依赖变量" + names);
			return this.names = names;
		}
	}	

	function dependenceInit()
	{
		var tName
			, i
			, j
			, deps
			, objNames
			, loader
			, subList = []
			, fileList = []
			, dep = this.dependence;
		//初始化 依赖 initialize it
		dep.init && dep.init();

		var pkg2 = dep.pkg2
			, scriptObjMap = dep.scriptObjectMap
			, fileName;
		for (fileName in scriptObjMap)
		{
			if (loader = pkg2.loaderMap[fileName])
			{
				if (loader.init)
				{
					if (loader.dependenceList)
					{
						subList.push.apply(subList, loader.dependenceList);
					}
					if (loader.dependenceMap)
					{
						if (dep.load == fileDependenceLoader)
						{
							for (tName in loader.dependenceMap)
							{
								subList.push.apply(subList, loader.dependenceMap[tName]); 
							}
						}
						else
						{
							objNames = scriptObjMap[fileName];
							for (i = objNames.length - 1; i >= 0; i--)
							{
								if (deps = loader.dependenceMap[objNames[i]])
								{
									subList.push.apply(subList, deps);
								}
							}
						}
					}
				}
			}
			else
			{
				if (!$JSI.getCacheScript(pkg2.name, fileName))
				{
					fileList.push(pkg2.scriptBase + fileName);
				}
				if (deps = pkg2.dependenceMap[fileName])
				{
					if (dep.load == fileDependenceLoader)
					{
						for (i = deps.length - 1; i >= 0; i--)
						{
							dep = deps[i];
							subList.push(dep[1] || dep);
						}
					}
					else
					{
						for (i = deps.length - 1; i >= 0; i--)
						{
							dep = deps[i];
							if (dep[1])
							{
								tName = dep[0];
								objNames = scriptObjMap[fileName];
								for (j = objNames.length - 1; j >= 0; j--)
								{
									if (objNames[j] == tName)
									{
										subList.push(dep[1]);
										break;
									}
								}
							}
							else
							{
								subList.push(dep); 
							}
						}
					}
				}
			}
		}
		if (fileList.length)
		{
			this.addTask(new FileLoadTask(fileList));
		}
		for (i = subList.length - 1; i >= 0; i--)
		{
			dep = subList[i];
			if (!this.scheduleMap[dep.id])
			{
				this.addTask(new DependenceLoadTask(dep, this.scheduleMap));
			}
		}
	}
	/*
	 * 获取指定实现包名(不存在则加载之) 
	 * @intenal 
	 * @param name 包名
	 */
	function requirePackage(name)
	{
		var pkg = findPackage(name);
		if (pkg)
		{
			if (pkg.implementation)
			{
				return requirePackage(pkg.implementation);
			}
			return pkg;
		}
	}

	function findObjectPackage(path)
	{
		//var pos = path.indexOf("."), mPath = mappedPath[path.substring(0, pos)];
		var pos;
		//$log.debug("findObjectPackage查找包内对象" + path);
		//path = mPath ? mPath + path.substr(pos) : path;
		return (pos = path.indexOf(":")) > 0 ? findPackage(path.substr(0, pos), true) : findPackage(path.replace(dotsRe, ""));
	}
	//值得优化 cacheAllPackage,不必探测空包 
	function findPackage(name, once)
	{
		//initialize 
		do
		{
			//$log.debug("findPackage查找名称" + name);
			//in op not support by ie5
			if (packageMap[name])
			{
				return packageMap[name];
			}
			if (packageMap[name] === undefined)
			{
				//$log.debug("findPackage未找到包,加载包脚本" + name);
				try
				{
					var pscript = $JSI.getCacheScript(name) || $JSI.loadURL(scriptBase + (name.replace(dot2dsRe, "/")) + "__package__.js");
				}
				catch(e)
				{
					//do nothing,continue
				}
				if (pscript)
				{
					//$log.debug("findPackage加载包脚本成功,建立包对象" + name);
					return new Package(name, pscript);
				}
				//$log.debug("findPackage未加载到包脚本" + name);
				//注册空包，避免重复探测
				packageMap[name] = null;
			}
			if(once)
				break;
		} while (name = name.replace(dotsRe, ""));
	}

	/*
	 * 构造异步导入任务 
	 * @private 
	 * @static 
	 */
	function buildImportTask(path)
	{
		var task, pos;
		if (path.charAt(pos = path.length - 1) == ":")
		{
			path = path.substr(0, pos);
			if (path = needLoadedPackage(path))
			{
				task = new PackageLoadTask(path);//仅加载包对象
			}
			else
			{
				//空队列 
				return null;
			}
		}
		else
		{
			var dep = new DependenceInfo;
			dep.pkg1 = packageMap["js.lang"] || {"objectScriptMap":{}};

			if (path.indexOf("*") > 0)
			{
				path = path.replace(dotRe, "/");
			}
			dep.target = path;

			if (path.indexOf("/") > 0)
			{
				dep.init = fileDependenceInit;
				dep.load = fileDependenceLoader;
			}
			task = new DependenceLoadTask(dep, {});
		}
		return task;
	}

	function runImportTask(root)
	{
		var task = root.currentTask || (root.currentTask = root)
			, subtask 
			, isHit
			, dotTextRe = /\.?\w+$/g
			, i
			, entries
			, entry;
		while (subtask = task.queue[task.index])
		{
			if (subtask instanceof PackageLoadTask)
			{
				entry = needLoadedPackage(subtask.name);
				if (entry)
				{
					if (subtask.names)
					{
						//以后的探测
						if (entry == subtask.name)
						{
							subtask.names.push(entry);
							entry = needLoadedPackage(entry.replace(dotTextRe, ""));
						}
					}
					else
					{
						subtask.names = [];
					}
					if (entry)
					{
						isHit = true;
						document.write("<scr" + "ipt type='text/javascript' src='" + scriptBase +
							(entry.replace(dotRe, "/")) + "/__package____preload__.js'></scr" + "ipt>");
						subtask.name = entry;
						break;
					}
				}

				//如果找到,注册空包
				if (packageMap[subtask.name] && (entries = subtask.names))
				{
					for (i = entries.length - 1; i >= 0; i--)
					{
						packageMap[entries[i]] = null;
					}
				}
				task.index++;
				break;
			}
			else if (subtask instanceof DependenceLoadTask)
			{
				task = root.currentTask = subtask;
			}
			else if (subtask instanceof LoadTask)
			{
				entries = subtask.urlList, entLen = entries.length;
				for (i = 0; i < entLen; i++)
				{
					isHit = true;
					document.write("<scr"+"ipt type='text/javascript' src='" + entries[i].replace(jsExtRe, "__preload__.js") + "'></scr"+"ipt>"); 
				}
				task.index++;
				break;
			}
			else if (subtask instanceof Function)
			{
				subtask.apply(task);
				task.index++;
			}
			else
			{
				$log.error("runImportTask任务定义错误", subtask);//throw new Error(subtask);
			}
		}
		if (!subtask)
		{
			task = task.parentTask;
			if (task)
			{
				root.currentTask = task;
				task.index++; 
			}
			else
			{
				root.fireEvent("success");
				if (lazyTasks.length > 1)
				{
					lazyTasks.shift();
				}
				else
				{
					return lazyTasks = null;
					
				}
			}
		}

		isHit ? document.write(lazyScript) : $JSI.runLazyTask();
	}
	//begin $import about 
	function doObjectImport(pkg, objName, target)
	{
		//do load
		/*if(!pkg)
			return $log.error("doObjectImport对象包定义错误" + objName);
		var objScriptMap = pkg.objectScriptMap
			, scriptName = objScriptMap[objName]
			, pos
			, obj;
		if(!scriptName)
		{
			return $log.error("doObjectImport未发现对象定义" + pkg.name + "." + objName);
		}*/
		var obj, pos;
		////$log.debug("doObjectImport加载对象脚本" + pkg.name + "." + objName);
		pkg.loadScript(pkg.objectScriptMap[objName], objName);
		////$log.debug("doObjectImport加载对象脚本成功" + pkg.name + "." + objName);

		if ((pos = objName.indexOf(".")) > 0)
		{
			objName = objName.substring(0, pos);
		}

		obj = pkg.objectMap[objName];
		return target ? target[objName] = obj : obj;
	}
	function doScriptImport(pkg, fileName, target)
	{
		if(typeof pkg == "string")
		{
			//$log.debug("doScriptImport加载文件脚本" + fileName);
			document.write("<scr" + "ipt type='text/javascript' src='" + fileName + "'></scr" + "ipt>");
		}
		else
		{
			//$log.debug("doScriptImport加载包脚本" + pkg.name + fileName);
			pkg.loadScript(fileName, "*");

			if (target)
			{
				for (var objNames = pkg.scriptObjectMap[fileName], i = objNames.length - 1; i >= 0 ; i--)
				{
					target[objNames[i]] = pkg.objectMap[objNames[i]]; 
				}
			}	
		}
	}
	function doStyleImport(pkg, cssPath, flag)
	{
		if(typeof pkg != "string")
		{
			cssPath = pkg.scriptBase + cssPath;
		}

		if (importedStyleMap[cssPath])
		{
			return;
		}
		//$log.debug("doStyleImport导入样式表" + cssPath);

		importedStyleMap[cssPath] = true;

		if (typeof flag != "function" && (flag || /loading/.test(document.readyState)))//_is(flag, Function)
		{
			document.write("<link rel='stylesheet' type='text/css' href='" + cssPath + "' />");
		}
		else
		{
			//异步装载或者 即时装载
			//for khtml; not sure the Safia 2 support? 
			var container = document.getElementsByTagName("head")[0] || document.getElementsByTagName("html")[0]
				,objCSS = container.appendChild(document.createElement("link"));
			with(objCSS)
			{
				rel = "stylesheet";
				href = cssPath;
				type = "text/css";	
			}
			container = objCSS = null;
		}
	}
	function doImport(path, callbackOrLazyLoad, target)
	{
		//$log.debug("doImport处理" + path);
		var pos = path.lastIndexOf("/")
			, pkg
			, objName
			, obj
			, nameLen
			, oName;

		if (pos > 0)
		{
			if(!(typeof callbackOrLazyLoad == "string"))//!_is(callbackOrLazyLoad, String)
			{
				pkg = findPackage(path.substring(0, pos).replace(dsRe, "."));
				if(!pkg)
					return $log.error("doImport加载路径包定义失败" + path);
				pkg = pkg.name;
				objName = path.substr(pkg.length + 1);
				pkg = requirePackage(pkg);
			}
			else
			{
				pkg = callbackOrLazyLoad;
				objName = path;
			}

			if (jsExtRe.test(objName))
			{
				doScriptImport(pkg, objName, target);
			}
			//文件导入
			else if (/\.css$/i.test(objName))
			{
				doStyleImport(pkg, objName, callbackOrLazyLoad); 
			}
			else
			{
				$log.error("doImport未知导入文件类型(需要.js或.css)" + path);
			}
		}
		else
		{
			path = mappedPath[path] || path;
			pkg = findObjectPackage(path);
			if(!pkg)
			{
				return $log.error("doImport加载包定义失败" + path);	
			}
			//$log.debug("doImport加载包对象成功" + pkg.name);
			pkg = pkg.name;
			objName = path.substr(pkg.length + 1);
			obj = pkg = requirePackage(pkg);
			////$log.debug("doImport加载包实体对象成功" + pkg.name);
			if (objName)
			{
				if (objName == "*")
				{
					//$log.debug("doImport预加载*对象" + pkg.name);
					for (oName in pkg.scriptObjectMap)
					{
						////$log.debug("doImport预加载" + pkg.name + "." + oName);
						doScriptImport(pkg, oName, target);
					}
					obj = target;
				}
				else
				{
					//$log.debug("doImport开始加载对象" + pkg.name + "." + objName);
					if(objName.charAt(nameLen = objName.length - 1) == "*")
					{
						var pName = objName.substr(0, nameLen);
						for(oName in pkg.objectScriptMap)
						{
							if(oName.indexOf(pName) == 0)
							{
								obj = doObjectImport(pkg, oName, target);
							}
						}
					}
					else
					{
						obj = doObjectImport(pkg, objName, target);
					}
					//$log.debug("doImport加载对象成功" + pkg.name + "." + objName);
				}
			}
			if (typeof callbackOrLazyLoad == "function")
			{
				callbackOrLazyLoad(obj);
			}
			return obj;
		}
	}

	/*
	 * @param path (package.ObjectName|package:|package.*) 
	 * @param <boolean|Function> callbackOrLazyLoad 可选参数(默认为全局变量,所以说,这种情况等价于直接声明的全局变量)，指定导入容器。 
	 * @param target 可选参数(默认为this,不过对于非对象成员函数调用时,this == window == global context,所以说,这种情况等价于直接声明的全局变量)，指定导入容器。 
	 * @return <void|object|package> 
	 */
	return function(path, callbackOrLazyLoad, target)
	{
		//$log.debug("$import加载" + path);
		var s = path.charAt(0);

		if(s == (".") || s == ("/") || path.indexOf("://") > -1)
		{
			return doImport(path, "S");
		}

		if(s = mappedPath[path.replace(/[:\.].*/, "")])
		{
			path = path.replace(/^[^:\.]*/, s);
		}

		s = null;//destroy

		if (arguments.length < 3)
		{
			target = this;//window
		}

		if (callbackOrLazyLoad)
		{
			var task = /\/.+\.css$/i.test(path) ? new PackageLoadTask(path.substr(0, path.lastIndexOf("/")).replace(dsRe, ".")) : buildImportTask(path);
			if (task)
			{
				function onSuccess()
				{
					doImport(path, callbackOrLazyLoad, target); 
				}

				task.addSuccessListener(onSuccess);
				if (typeof callbackOrLazyLoad =="function")//回调函数
				{
					task.start();
				}
				else
				{
					if (!lazyTasks)
					{
						lazyTasks = [task];
						document.write(lazyScript); 
					}
					else
					{
						lazyTasks.push(task);
					}
				}
				return;
			}
		}

		return doImport(path, callbackOrLazyLoad, target);
	}
}
(function(v)
{
	this.hook = function(s)
	{
		return eval(s);
	}
	eval(this.varText);
	eval(v);
}
);